diff options
Diffstat (limited to 'src/app/anime/[id]')
| -rw-r--r-- | src/app/anime/[id]/[animeId]/page.jsx | 56 | ||||
| -rw-r--r-- | src/app/anime/[id]/[animeId]/video.css | 30 | ||||
| -rw-r--r-- | src/app/anime/[id]/info.css | 83 | ||||
| -rw-r--r-- | src/app/anime/[id]/loading.css | 346 | ||||
| -rw-r--r-- | src/app/anime/[id]/loading.jsx | 9 | ||||
| -rw-r--r-- | src/app/anime/[id]/page.jsx | 50 |
6 files changed, 574 insertions, 0 deletions
diff --git a/src/app/anime/[id]/[animeId]/page.jsx b/src/app/anime/[id]/[animeId]/page.jsx new file mode 100644 index 0000000..d59b0a0 --- /dev/null +++ b/src/app/anime/[id]/[animeId]/page.jsx @@ -0,0 +1,56 @@ +import { MediaPlayer, MediaProvider } from "@vidstack/react"; +import "@vidstack/react/player/styles/base.css"; +import "@vidstack/react/player/styles/plyr/theme.css"; +import { + PlyrLayout, + plyrLayoutIcons, +} from "@vidstack/react/player/layouts/plyr"; +import "./video.css"; +import { redirect } from "next/navigation"; + +export default async function Video({ params }) { + const id = params.animeId; + + // Getting the episode number and the anime name. Kindly ignore! + const words = id.split("-"); + const last_two = words.slice(-2).join(" "); + const remainingWords = words.slice(0, -2).join(" "); + + const data = await getVideoLink(id); + + if (data.message) { + redirect("/404"); + } + + const link = data.sources[4].url; + + return ( + <div> + <div className="video2"> + <p> + {last_two} - {remainingWords} + </p> + <MediaPlayer + title={words} + src={link} + className="testPlayer" + playsInline + aspectRatio="16/9" + load="eager" + > + <MediaProvider /> + <PlyrLayout icons={plyrLayoutIcons} /> + </MediaPlayer> + </div> + </div> + ); +} + +async function getVideoLink(id) { + const res = await fetch( + "https://consumet-api-di2e.onrender.com/anime/gogoanime/watch/" + id, + { next: { revalidate: 3600 } } // Video links are revalidated after an hour + ); + const data = res.json(); + return data; +} diff --git a/src/app/anime/[id]/[animeId]/video.css b/src/app/anime/[id]/[animeId]/video.css new file mode 100644 index 0000000..5ccb58f --- /dev/null +++ b/src/app/anime/[id]/[animeId]/video.css @@ -0,0 +1,30 @@ +.video2 { + display: flex; + flex-direction: column; + align-items: center; + margin: 0px auto; + width: 50%; +} + +.testPlayer { + border-radius: 10px; +} + +.video2 p { + color: white; + font-family: "Lato"; + font-size: 20px; + text-align: center; +} + +@media (prefers-color-scheme: light) { + .video2 p { + color: black; + } +} + +@media screen and (max-width: 768px) { + .video2 { + width: 100%; + } +}
\ No newline at end of file diff --git a/src/app/anime/[id]/info.css b/src/app/anime/[id]/info.css new file mode 100644 index 0000000..2b070d0 --- /dev/null +++ b/src/app/anime/[id]/info.css @@ -0,0 +1,83 @@ +.dramaInfoContainer { + display: flex; + flex-direction: column; +} + +.dramaInfo { + display: flex; + flex-direction: column; + width: 95%; + margin: 0px auto; +} + +.titleContainer { + display: flex; + justify-content: space-between; + align-items: center; +} + +.titleContainer p { + color: var(--neon-green); + width: 60%; + font-family: "Kanit"; + font-size: 24px; +} + +.titleContainer img { + border-radius: 10px; +} + +.animeDescription { + color: #ffffff81; + font-family: "Lato"; + font-size: 16px; + max-height: 120px; + margin: 20px auto; + text-align: center; + overflow-y: auto; +} + +.buttonContainer { + margin: 5px auto; + text-align: center; + max-height: 200px; + overflow-y: auto; +} + +.dramaButton { + padding: 8px; + font-family: "Atkinson Hyperlegible"; + font-size: 18px; + margin: 5px; + width: 50px; + border-radius: 5px; + border: none; + background-color: var(--light-green); + cursor: pointer; +} + +.dramaButton:hover { + background-color: var(--soft-purple); +} + +.infoPageContainer { + display: flex; + height: 100dvh; + justify-content: center; + align-items: center; +} + +.infoPageContainer p { + color: white; +} + +@media (prefers-color-scheme: light) { + .animeDescription { + color: black; + } + + .infoPageContainer p { + color: black; + } + +}
\ No newline at end of file diff --git a/src/app/anime/[id]/loading.css b/src/app/anime/[id]/loading.css new file mode 100644 index 0000000..aa3a519 --- /dev/null +++ b/src/app/anime/[id]/loading.css @@ -0,0 +1,346 @@ +.loadingContainer { + color: white; + display: flex; + justify-content: center; + align-items: center; + height: 80dvh; +} + + +.text-flicker-in-glow { + -webkit-animation: text-flicker-in-glow 4s linear both; + animation: text-flicker-in-glow 4s linear both; + font-size: 36px; + font-family: "Kanit"; +} + +/* ---------------------------------------------- + * Generated by Animista on 2024-3-21 9:58:16 + * Licensed under FreeBSD License. + * See http://animista.net/license for more info. + * w: http://animista.net, t: @cssanimista + * ---------------------------------------------- */ + +/** + * ---------------------------------------- + * animation text-flicker-in-glow + * ---------------------------------------- + */ + +@-webkit-keyframes text-flicker-in-glow { + 0% { + opacity: 0; + } + + 10% { + opacity: 0; + text-shadow: none; + } + + 10.1% { + opacity: 1; + text-shadow: none; + } + + 10.2% { + opacity: 0; + text-shadow: none; + } + + 20% { + opacity: 0; + text-shadow: none; + } + + 20.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.25); + } + + 20.6% { + opacity: 0; + text-shadow: none; + } + + 30% { + opacity: 0; + text-shadow: none; + } + + 30.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.5% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.6% { + opacity: 0; + text-shadow: none; + } + + 45% { + opacity: 0; + text-shadow: none; + } + + 45.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 50% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55.1% { + opacity: 0; + text-shadow: none; + } + + 57% { + opacity: 0; + text-shadow: none; + } + + 57.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60.1% { + opacity: 0; + text-shadow: none; + } + + 65% { + opacity: 0; + text-shadow: none; + } + + 65.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75.1% { + opacity: 0; + text-shadow: none; + } + + 77% { + opacity: 0; + text-shadow: none; + } + + 77.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85.1% { + opacity: 0; + text-shadow: none; + } + + 86% { + opacity: 0; + text-shadow: none; + } + + 86.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 100% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } +} + +@keyframes text-flicker-in-glow { + 0% { + opacity: 0; + } + + 10% { + opacity: 0; + text-shadow: none; + } + + 10.1% { + opacity: 1; + text-shadow: none; + } + + 10.2% { + opacity: 0; + text-shadow: none; + } + + 20% { + opacity: 0; + text-shadow: none; + } + + 20.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.25); + } + + 20.6% { + opacity: 0; + text-shadow: none; + } + + 30% { + opacity: 0; + text-shadow: none; + } + + 30.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.5% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 30.6% { + opacity: 0; + text-shadow: none; + } + + 45% { + opacity: 0; + text-shadow: none; + } + + 45.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 50% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.45), 0 0 60px rgba(255, 255, 255, 0.25); + } + + 55.1% { + opacity: 0; + text-shadow: none; + } + + 57% { + opacity: 0; + text-shadow: none; + } + + 57.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35); + } + + 60.1% { + opacity: 0; + text-shadow: none; + } + + 65% { + opacity: 0; + text-shadow: none; + } + + 65.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.35), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 75.1% { + opacity: 0; + text-shadow: none; + } + + 77% { + opacity: 0; + text-shadow: none; + } + + 77.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.55), 0 0 60px rgba(255, 255, 255, 0.4), 0 0 110px rgba(255, 255, 255, 0.2), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 85.1% { + opacity: 0; + text-shadow: none; + } + + 86% { + opacity: 0; + text-shadow: none; + } + + 86.1% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } + + 100% { + opacity: 1; + text-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1); + } +} + +@media (prefers-color-scheme: light) { + .loadingContainer { + color: black; + } +}
\ No newline at end of file diff --git a/src/app/anime/[id]/loading.jsx b/src/app/anime/[id]/loading.jsx new file mode 100644 index 0000000..dfa397c --- /dev/null +++ b/src/app/anime/[id]/loading.jsx @@ -0,0 +1,9 @@ +import "./loading.css"; + +export default function Loading() { + return ( + <div className="loadingContainer"> + <p className="text-flicker-in-glow">Loading</p> + </div> + ); +} diff --git a/src/app/anime/[id]/page.jsx b/src/app/anime/[id]/page.jsx new file mode 100644 index 0000000..3e2b1f0 --- /dev/null +++ b/src/app/anime/[id]/page.jsx @@ -0,0 +1,50 @@ +import "./info.css"; +import Image from "next/image"; +import Link from "next/link"; + +export default async function AnimeInfo({ params }) { + let animeID = params.id; + + const info = await getAnimeInfo(animeID); + + return ( + <div className="dramaInfoContainer"> + <div className="dramaInfo"> + {info && ( + <div> + <div className="titleContainer"> + <p>{info.title}</p> + <Image + src={info.image} + width={140} + height={190} + alt="Drama" + /> + </div> + <p className="animeDescription">{info.description}</p> + </div> + )} + + <div className="buttonContainer"> + {info && + info.episodes.map((item, index) => ( + <Link href={`/anime/watch/${item.id}`} key={index}> + <button className="dramaButton"> + {item.number} + </button> + </Link> + ))} + </div> + </div> + </div> + ); +} + +async function getAnimeInfo(anime_id) { + const res = await fetch( + "https://anime-sensei-api.vercel.app/anime/gogoanime/info/" + anime_id, + { next: { revalidate: 1800 } } + ); + const data = res.json(); + return data; +} |